package cn.cutie.clotconfig.client.repository;

import cn.cutie.clotconfig.client.config.ConfigMeta;
import cn.kimmking.utils.HttpUtils;
import com.alibaba.fastjson.TypeReference;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @Description: 获取远程配置默认实现
 * @Author: Cutie
 * @CreateDate: 2024/5/10 22:11
 * @Version: 0.0.1
 */

public class ClotRepositoryImpl implements ClotRepository{
    ConfigMeta configMeta;

    Map<String, Long> versionMap = new HashMap<>();

    Map<String, Map<String, String>> configMap = new HashMap<>();

    ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);

    List<ClotRepositoryChangeListener> listeners = new ArrayList<>();

    public ClotRepositoryImpl(ConfigMeta configMeta) {
        this.configMeta = configMeta;
        executor.scheduleWithFixedDelay(this::heartBeat, 1000, 5000, TimeUnit.MILLISECONDS);
    }

    public void addListener(ClotRepositoryChangeListener listener) {
        listeners.add(listener);
    }

    @Override
    public Map<String, String> getConfig() {
        String key = configMeta.genKey();
        if (configMap.containsKey(key)){
            return configMap.get(key);
        }
        Map<String, String> resultMap = findAll();
        return resultMap;
    }

    private Map<String, String> findAll() {
        String listPath = configMeta.listPath();
        System.out.println("[CLOTCONFIG] list all configs from clot server");
        List<Configs> configs = HttpUtils.httpGet(listPath, new TypeReference<List<Configs>>(){});
        Map<String, String> resultMap = new HashMap<>();
        configs.forEach(c -> resultMap.put(c.getPkey(), c.getPval()));
        return resultMap;
    }

    private void heartBeat() {
        String versionPath = configMeta.versionPath();
        Long version = HttpUtils.httpGet(versionPath, new TypeReference<Long>() {});
        String key = configMeta.genKey();
        Long oldVersion = versionMap.getOrDefault(key, -1L);
        if (version > oldVersion){
            System.out.println("[CLOTCONFIG] version need update, current version: " + version + ", old version" + oldVersion);
            versionMap.put(key, version);
            Map<String, String> newConfigs = findAll();
            configMap.put(key, newConfigs);
            // 发生变化，重新绑定属性！！
            // org.springframework.cloud.context.properties.ConfigurationPropertiesRebinder.onApplicationEvent 中的 EnvironmentChangeEvent
            listeners.forEach(listener -> listener.onChange(new ClotRepositoryChangeListener.ChangeEvent(configMeta, newConfigs)));
        }
    }

}
